package edu.del.newsreleasesystem.comfirm;

import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * 统一管理 RabbitMQ 消息投递确认（ConfirmCallback）的回调逻辑，
 * 并根据 callbackBeanName 分发到对应的 ConfirmCallbackService 实现类
 */
@Component
@RequiredArgsConstructor
@Slf4j
public class ConfirmCallbackContext {

    private final RabbitTemplate rabbitTemplate;

    private final Map<String, ConfirmCallbackService> confirmCallbackServiceMap;

    // Jackson 对象映射器，用于序列化/反序列化消息
    private final ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 初始化时设置 ConfirmCallback，处理消息是否成功到达 Exchange
     */
    @PostConstruct
    public void confirmCallback() {
        rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
            if (ack) {
                log.info("消息成功投递到 Exchange");
            } else {
                log.warn("消息投递到 Exchange 失败！原因: {}", cause);

                // 我们使用的是自定义的 MyCorrelationData
                if (correlationData instanceof MyCorrelationData) {
                    MyCorrelationData myData = (MyCorrelationData) correlationData;
                    // 如 "newsServiceImpl"
                    String beanName = myData.getCallbackBeanName();
                    // 原始业务对象，如 NewsSyncMessage
                    Object originalMessage = myData.getMessage();

                    // 根据 beanName 获取对应的业务回调处理器
                    ConfirmCallbackService callbackService = confirmCallbackServiceMap.get(beanName);
                    if (callbackService != null) {
                        try {
                            // 序列化原始消息为 Message 类型（或者直接传递业务对象，但要调整接口）
                            // 这里为了通用性，我们序列化为 byte[] 再包装为 Message
                            byte[] body = objectMapper.writeValueAsBytes(originalMessage);
                            Message message = new Message(body);
                            callbackService.confirmCallback(message);
                        } catch (Exception e) {
                            log.error("处理失败回调时序列化消息失败", e);
                        }
                    } else {
                        log.error("未找到对应的回调服务 Bean: {}", beanName);
                    }
                } else {
                    log.error("当前 CorrelationData 不是 MyCorrelationData 类型，无法提取回调信息");
                }
            }
        });
    }


}